#include "scenetree.h"
#include "scenenode.h"
#include <sstream>

SceneTree::NameExtractor::NameExtractor(std::string names)
	:mNameString(names)
	,mPos()
	,mCount()
{
}

SceneTree::NameExtractor::~NameExtractor()
{
}

std::string SceneTree::NameExtractor::getName()
{
	std::string node_name;
	if (mPos == -1)
	{
		node_name = "";
	}else
	{
		mCount = mNameString.find('/', mPos+1) - mPos - 1;
		node_name = mNameString.substr(mPos+1, mCount);
		mPos += mCount+1;
	}
	return node_name;
}

SceneTree::SceneTree()
	:mRoot()
{
	mRoot = new SceneNode(".");
}

SceneTree::~SceneTree()
{
	if (mRoot)
	{
		delete mRoot;
		mRoot = NULL;
	}
}

void SceneTree::makePath(const std::string &path)
{
	std::string node_name;
	NameExtractor ex(path);
	SceneNode *node = mRoot;
	for(node_name = ex.getName(); !node_name.empty(); node_name = ex.getName())
	{
		SceneNode *tmp;
		
		if (!node->getChild(node_name))
		{
			tmp = new SceneNode(node_name);
			node->addChild(tmp);
		} else
		{
			tmp = node->getChild(node_name);
		}

		node = tmp;
	}
}

SceneNode *SceneTree::getChild(const std::string &path)
{
	NameExtractor ex(path);
	std::string name;
	SceneNode *node= mRoot;
	for(name = ex.getName(); !name.empty(); name = ex.getName())
	{
		if (node && node->getChild(name))
			node = node->getChild(name);
		else
			return NULL;
	}
	return node;
}

const SceneNode *SceneTree::getChild(const std::string &path)
	const
{
	NameExtractor ex(path);
	std::string name;
	SceneNode *node= mRoot;
	for(name = ex.getName(); !name.empty(); name = ex.getName())
	{
		if (node && node->getChild(name))
			node = node->getChild(name);
		else
			return NULL;
	}
	return node;
}

void SceneTree::removeChild(const std::string &path)
{
	NameExtractor ex(path);
	std::string name;
	SceneNode *node= mRoot;
	SceneNode *prev = NULL;
	for(name = ex.getName(); !name.empty(); name = ex.getName())
	{
		if (node && node->getChild(name))
		{
			prev = node;
			node = node->getChild(name);
		}else 
			break;
	}
	prev->removeChild(node->getName());
}

void SceneTree::addChild(const std::string &path, SceneNode *child)
{
	SceneNode *node = getChild(path);
	if (node)
		node->addChild(child);
}

std::string SceneTree::getPathList()
{
	std::stringstream stream;
	stream << "not now";
	return stream.str();
}